{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a0640b26",
   "metadata": {},
   "source": [
    "--------\n",
    "* 记录人：刘心怡   \n",
    "* 时间：2021-11-29  \n",
    "* week14   \n",
    "* 主要参考文档:\n",
    "> 1. [Python官方文档](https://python.org/doc)\n",
    "> 2. [博客--函数](https://www.cnblogs.com/xuzhichao/p/11570285.html)\n",
    "\n",
    "--------"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43c24326",
   "metadata": {},
   "source": [
    "# 本周内容\n",
    "\n",
    "> 1. 函数的定义\n",
    "\n",
    "> 2. 如何使用函数\n",
    "\n",
    "> 3. 函数的返回值\n",
    "\n",
    "> 4. 使用注释改进文档\n",
    "\n",
    "> 5. 传递任意数量的实参\n",
    "\n",
    ">6. 函数与模块\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0cb5799",
   "metadata": {},
   "source": [
    "## 1. 函数的定义\n",
    "\n",
    "* 定义函数\n",
    "> 1. def 定义函数的第一步\n",
    "> 2. def function_name\n",
    ">> 1. function_name 遵循变量名称定义的规则\n",
    "> 3. 函数名称后加上\"(): \" def_function(): ===> f(x) = 2x\n",
    "\n",
    "* 书写函数体\n",
    "> 1.函数的注释\n",
    "> 2.写函数的具体操作（函数体）\n",
    "> 3.注意：函数也是需要有tab键的间距\n",
    "\n",
    "* 使用函数的（函数的调用）\n",
    "> 1. function_name()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "459445ba",
   "metadata": {},
   "outputs": [],
   "source": [
    "def fib(n):    # write Fibonacci series up to n\n",
    "    \"\"\"Print a Fibonacci series up to n.\"\"\"\n",
    "    a, b = 0, 1\n",
    "    while a < n:\n",
    "        print(a, end=' ')\n",
    "        a, b = b, a+b\n",
    "    print()\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "68a8ca2f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 55 89 \n"
     ]
    }
   ],
   "source": [
    "fib(100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "d22c0ed1",
   "metadata": {},
   "outputs": [],
   "source": [
    "##  尝试：写一个实现hello world的函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "5c79324f",
   "metadata": {},
   "outputs": [],
   "source": [
    "def hello():\n",
    "    \"\"\"打印hello world\"\"\"\n",
    "    print(\"hello world!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "d80cb566",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world!\n"
     ]
    }
   ],
   "source": [
    "hello()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4b3c7f0c",
   "metadata": {},
   "source": [
    "## 如何使用函数（课本实践p149）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "2df2a218",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 思考函数存在的意义？\n",
    "# 1. 可以通过调用函数的方式实现某个功能，使用人无需考虑代码的内容\n",
    "# 2. 节省时间，提升应用效率\n",
    "# 3. 函数一旦定义，就可按照一定的规则重复使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "002bd2ee",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义一个名字为 search4vowels 的函数\n",
    "def search4vowels(word):\n",
    "    \"\"\"打印文本中出现的元音字母,输入你想要的内容\"\"\"\n",
    "    vowels = set('aeiou')\n",
    "    # word = input(\"Provide a word to search for vowels:\")\n",
    "    found = vowels.intersection(set(word))  # 交集运算\n",
    "    print(found)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "bc7cb541",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a'}\n"
     ]
    }
   ],
   "source": [
    "search4vowels(\"adjkfbkdajw\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "ac950510",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 下面的方法是不是太重复了，主要原因是没有对重复功能的代码块有特殊的定义（如：名称，注释等）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "399e1a1c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Provide a word to search for vowels:sdhdhdhhddkowjadm\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'a', 'o'}"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vowels = set('aeiou')\n",
    "word = input(\"Provide a word to search for vowels:\")\n",
    "found = vowels.intersection(set(word))\n",
    "found"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2ef36c99",
   "metadata": {},
   "source": [
    "## 函数的参数\n",
    "\n",
    "* <font style=\"color:red\">注意：函数的参数可以没有,如果有参数，则如下（分为形参和实参）：</font>\n",
    "\n",
    "> 1. 形式参数\n",
    ">> 1. 在定义过程中，函数的参数为形式参数\n",
    ">> 2. 形式参数是虚拟的，不占用空间\n",
    "> 2. 实际参数\n",
    ">> 1. 调用函数过程中，函数的参数为实际参数\n",
    ">> 2. 调用函数时，形式参数被分配空间，成为实际参数并应用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "7fd06e04",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world!\n"
     ]
    }
   ],
   "source": [
    "# 函数是可以没有参数的\n",
    "hello()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "ee95097e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello,Xinyi!\n"
     ]
    }
   ],
   "source": [
    "## 定义函数\n",
    "def greet_user(username):    \n",
    "    \"\"\"显示简单的问候语\"\"\"    \n",
    "    print(\"hello,\"+username.title()+\"!\")         \n",
    "\n",
    "## 调用函数    \n",
    "greet_user(\"xinyi\")  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c773141d",
   "metadata": {},
   "source": [
    "---\n",
    "* 当参数不止一个时：\n",
    "> 1. 位置参数(positional argument)\n",
    ">> 1. 形式参数有多个值，如果实际参数直接赋值，要按照形式参数的先后顺序，这种方式称：位置参数赋值\n",
    ">> 2. 在调用函数过程中需要考虑如下：\n",
    ">>> 1. 考虑位置\n",
    ">>> 2. 考虑个数\n",
    "> 2. 关键字参数\n",
    ">> 1. 在调用函数时使用，我们直接在实参中 用赋值的方式去定义形参\n",
    ">> 2. 不需要考虑顺序，因为赋值已经确定了形式参数的值\n",
    "> 3. 默认参数\n",
    ">> 1. 默认参数写在 形式参数中\n",
    ">> 2. 默认参数存在的话，实际调用过程中可以省略赋值的过程\n",
    "---"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "d19fc3ac",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 两个参数\n",
    "\n",
    "def describe_pet(animal_type,pet_name):\n",
    "    \"\"\"显示宠物信息\"\"\"\n",
    "    print(\"\\nI have a \" + animal_type + \".\")\n",
    "    print(\"My \" + animal_type + \"'s name is \"+pet_name.title() + \".\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "4158d930",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "My dog's name is 逗逗.\n"
     ]
    }
   ],
   "source": [
    "describe_pet('dog','逗逗')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "1f3a86f9",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "describe_pet() missing 1 required positional argument: 'pet_name'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-32-5208887e1c6b>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdescribe_pet\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"cat\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m: describe_pet() missing 1 required positional argument: 'pet_name'"
     ]
    }
   ],
   "source": [
    "describe_pet(\"cat\")  # 只有一个则会报错"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "c6cf9485",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "My dog's name is 逗逗.\n"
     ]
    }
   ],
   "source": [
    "# 关键字参数\n",
    "describe_pet(animal_type=\"dog\",pet_name=\"逗逗\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "c715d97c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "My dog's name is 逗逗.\n"
     ]
    }
   ],
   "source": [
    "# 关键字参数 可随意调动位置\n",
    "describe_pet(pet_name=\"逗逗\",animal_type=\"dog\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "f99bb1be",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "My dog's name is 逗逗.\n"
     ]
    }
   ],
   "source": [
    "# 默认参数(写在形式参数中的)\n",
    "def describe_pet(pet_name,animal_type=\"dog\"):\n",
    "    \"\"\"显示宠物信息，animal_type 的默认值 'dog'\"\"\"\n",
    "    print(\"\\nI have a \" + animal_type + \".\")\n",
    "    print(\"My \" + animal_type + \"'s name is \"+pet_name.title() + \".\")\n",
    "describe_pet(\"逗逗\",\"dog\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8fc79bcc",
   "metadata": {},
   "source": [
    "---\n",
    "* 实操和注意（参数部分）positional argument follows keyword argument\n",
    "\n",
    "> 1. 如果想 关键字参数 和 位置参数共同使用\n",
    ">> 1. positional argument follows keyword argument(位置参数需要放在关键字参数的前面)\n",
    ">> 2. 关键字参数放在末尾（均是关键字，不考虑顺序）\n",
    "> 2. 默认参数\n",
    ">> 1. non-default argument follows default argument(非默认参数需要放在默认参数的前面)\n",
    ">> 2. 默认参数放在末尾（均是默认参数，不考虑顺序）\n",
    "---"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "854fa4ef",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "positional argument follows keyword argument (<ipython-input-43-26b098ea64bc>, line 6)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  File \u001b[0;32m\"<ipython-input-43-26b098ea64bc>\"\u001b[0;36m, line \u001b[0;32m6\u001b[0m\n\u001b[0;31m    func_test(x=1,2)      #？\u001b[0m\n\u001b[0m                  ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m positional argument follows keyword argument\n"
     ]
    }
   ],
   "source": [
    "#eg1 \n",
    "def func_test(x,y):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    \n",
    "func_test(x=1,2)      #？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "4120e5bc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "1\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "#eg2\n",
    "def func_test(x,y,z):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)\n",
    "    \n",
    "func_test(2,1,z=3)      "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "e5deca8c",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "non-default argument follows default argument (<ipython-input-45-72e60920b1b2>, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  File \u001b[0;32m\"<ipython-input-45-72e60920b1b2>\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m    def func_test(x,y=4,z):\u001b[0m\n\u001b[0m                  ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m non-default argument follows default argument\n"
     ]
    }
   ],
   "source": [
    "#eg3\n",
    "def func_test(x,y=4,z):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)\n",
    "    \n",
    "func_test(2,1,3)    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "b812bd13",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "5\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "#eg3\n",
    "def func_test(x,z,y=3):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)\n",
    "    \n",
    "func_test(2,3,5)    "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
